using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Book.Blog.Core.DTOs;
using Book.Blog.Core.Entities;
using Book.Blog.Infrastructure.Services;
using Book.Blog.API.Examples;
using Swashbuckle.AspNetCore.Annotations;
using Swashbuckle.AspNetCore.Filters;

namespace Book.Blog.API.Controllers
{
    /// <summary>
    /// 认证控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    [SwaggerTag("用户认证相关接口")]
    public class AuthController : ControllerBase
    {
        private readonly UserManager<User> _userManager;
        private readonly SignInManager<User> _signInManager;
        private readonly JwtService _jwtService;

        public AuthController(
            UserManager<User> userManager,
            SignInManager<User> signInManager,
            JwtService jwtService)
        {
            _userManager = userManager;
            _signInManager = signInManager;
            _jwtService = jwtService;
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="model">登录信息</param>
        /// <returns>登录结果</returns>
        /// <remarks>
        /// 示例请求:
        /// {
        ///   "email": "admin@example.com",
        ///   "password": "Admin123!"
        /// }
        /// </remarks>
        /// <response code="200">登录成功</response>
        /// <response code="401">邮箱或密码错误</response>
        [HttpPost("login")]
        [SwaggerResponse(200, "登录成功", typeof(LoginResultDTO))]
        [SwaggerResponseExample(200, typeof(LoginResponseExample))]
        [SwaggerOperation(
            Summary = "用户登录",
            Description = "使用邮箱和密码登录系统",
            OperationId = "Auth_Login",
            Tags = new[] { "认证" }
        )]
        public async Task<ActionResult<LoginResultDTO>> Login(LoginDTO model)
        {
            var user = await _userManager.FindByEmailAsync(model.Email);
            if (user == null)
            {
                return Unauthorized("邮箱或密码错误");
            }

            var result = await _signInManager.CheckPasswordSignInAsync(user, model.Password, false);
            if (!result.Succeeded)
            {
                return Unauthorized("邮箱或密码错误");
            }

            // 更新最后登录时间
            user.LastLoginTime = DateTime.UtcNow;
            await _userManager.UpdateAsync(user);

            return new LoginResultDTO
            {
                Token = _jwtService.GenerateJwtToken(user),
                UserName = user.UserName,
                Email = user.Email,
                Avatar = user.Avatar
            };
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="model">注册信息</param>
        /// <returns>注册结果</returns>
        /// <remarks>
        /// 示例请求:
        /// {
        ///   "userName": "newuser",
        ///   "email": "newuser@example.com",
        ///   "password": "NewUser123!",
        ///   "confirmPassword": "NewUser123!"
        /// }
        /// </remarks>
        /// <response code="200">注册成功</response>
        /// <response code="400">注册信息无效</response>
        [HttpPost("register")]
        [SwaggerOperation(
            Summary = "用户注册",
            Description = "注册新用户账号",
            OperationId = "Auth_Register",
            Tags = new[] { "认证" }
        )]
        public async Task<ActionResult> Register(RegisterDTO model)
        {
            if (model.Password != model.ConfirmPassword)
            {
                return BadRequest("两次输入的密码不一致");
            }

            var user = new User
            {
                UserName = model.UserName,
                Email = model.Email
            };

            var result = await _userManager.CreateAsync(user, model.Password);
            if (!result.Succeeded)
            {
                return BadRequest(result.Errors);
            }

            // 发送确认邮件
            var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            // TODO: 发送确认邮件

            return Ok("注册成功，请查收确认邮件");
        }

        /// <summary>
        /// 忘记密码
        /// </summary>
        /// <param name="model">忘记密码信息</param>
        /// <returns>操作结果</returns>
        /// <remarks>
        /// 示例请求:
        /// {
        ///   "email": "user@example.com"
        /// }
        /// </remarks>
        /// <response code="200">重置密码邮件已发送</response>
        [HttpPost("forgot-password")]
        [SwaggerOperation(
            Summary = "忘记密码",
            Description = "发送重置密码邮件",
            OperationId = "Auth_ForgotPassword",
            Tags = new[] { "认证" }
        )]
        public async Task<ActionResult> ForgotPassword(ForgotPasswordDTO model)
        {
            var user = await _userManager.FindByEmailAsync(model.Email);
            if (user == null)
            {
                // 出于安全考虑，即使用户不存在也返回成功
                return Ok("如果该邮箱已注册，你将收到重置密码的邮件");
            }

            var token = await _userManager.GeneratePasswordResetTokenAsync(user);
            // TODO: 发送重置密码邮件

            return Ok("重置密码邮件已发送，请查收");
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="model">重置密码信息</param>
        /// <returns>操作结果</returns>
        /// <remarks>
        /// 示例请求:
        /// {
        ///   "email": "user@example.com",
        ///   "token": "reset-token",
        ///   "newPassword": "NewPassword123!",
        ///   "confirmNewPassword": "NewPassword123!"
        /// }
        /// </remarks>
        /// <response code="200">密码重置成功</response>
        /// <response code="400">重置信息无效</response>
        [HttpPost("reset-password")]
        [SwaggerOperation(
            Summary = "重置密码",
            Description = "使用重置令牌重置密码",
            OperationId = "Auth_ResetPassword",
            Tags = new[] { "认证" }
        )]
        public async Task<ActionResult> ResetPassword(ResetPasswordDTO model)
        {
            if (model.NewPassword != model.ConfirmNewPassword)
            {
                return BadRequest("两次输入的密码不一致");
            }

            var user = await _userManager.FindByEmailAsync(model.Email);
            if (user == null)
            {
                return BadRequest("无效的请求");
            }

            var result = await _userManager.ResetPasswordAsync(user, model.Token, model.NewPassword);
            if (!result.Succeeded)
            {
                return BadRequest(result.Errors);
            }

            return Ok("密码重置成功");
        }
    }
} 